using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Reflection;
using System.CodeDom.Compiler;
using System.Runtime.Serialization;

namespace NBusiness.CodeDom.Compiler
{
    [Serializable]
	public abstract class EntityProvider : IServiceProvider
	{
        public abstract EntityCompiler GetCompiler();
        public abstract EntityParser GetParser();
        public abstract EntityGenerator GetGenerator();

        #region IServiceProvider Members
        [NonSerialized]
        private Dictionary<Type, object> _nonSerializedServices = new Dictionary<Type, object>();
        private Dictionary<Type, object> _serializedServices = new Dictionary<Type, object>();
        
        
        /// <summary>
        /// Register external services for this provider to use. Service types used by this provider:
        /// 
        ///      ITypeFinderService
        ///      IBuildErrorService
        ///      ISettingsService
        /// </summary>
        /// <param name="serviceType">The type of the service to be registered as</param>
        /// <param name="service">The instance of the service to register</param>
        public void SetService(Type serviceType, object service)
        {
            if (_nonSerializedServices.ContainsKey(serviceType))
                _nonSerializedServices.Remove(serviceType);

            if (_serializedServices.ContainsKey(serviceType))
                _serializedServices.Remove(serviceType);

            if(service.GetType().IsDefined(typeof(SerializableAttribute), false) || typeof(ISerializable).IsAssignableFrom(service.GetType()))
                _serializedServices.Add(serviceType, service);

            else
                _nonSerializedServices.Add(serviceType, service);
        }

        public object GetService(Type serviceType)
        {
            if (_nonSerializedServices != null && _nonSerializedServices.ContainsKey(serviceType))
                return _nonSerializedServices[serviceType];

            if (_serializedServices.ContainsKey(serviceType))
                return _serializedServices[serviceType];

            return null;
        }

        #endregion
    }
}
